#pragma once
#include "imagematrix.h"
// "longinstance.h"



/**
 * This class combines 8 imagematrix into one object. It is an array of 8 image matrices and has accessors and mutators 
 * for each pixel in each imagematrix. As of July 2011, I still have no class/function to read grayscale images, so I use
 * this class for now. 
 */
 class EightLayerIM
 {
 private:
	 ImageMatrix image[8];	//!<The array of image matrices, one per bit order.
	 int validImages;			//!<Tells how many of the imagematrices have valid values. e.g. validImages=2 means that only bit0 and bit1 are valid.

 public:
	 /** Prints out the layer whose index is gicen. */
	 void printLayer (int layerNum) const;
	 void setvalidImages (int b = 0) {this->validImages = b;}
	 int getValidImages () const {return this->validImages;}

	 /** adds a new ImageMatrix object to this object and increments validImages. */
	 void addImageMatrix (const ImageMatrix& newIM);

	 ImageMatrix getImage(int index) const {return this->image[index];}

	 /** creates a LongInstance using the first 'ifSize' images and returns at in the targetLI input parameter. 
	  * \param row, col the coordinate of the pixel for whom the long instance will be created.
	  * \param ifSize tells how many imagematrices should be used in making the IF part of the target. 
	  * ifSize = 1 means use only the first image to create a LongInstance that has only one neighborhood. 
	  * Therefore, 1 <= ifSize <= validImages-1.
	  * \param [in] stores the result rule.
	  */
	 //void updateLongInstance (int row, int col, int ifSize, LongInstance& targetLI) const;

	 ///** Similar to updateLongInstance() but returns a LongInstance object and does not get an output parameter. */
	 //LongInstance& makeLongInstance (int row, int col, int ifSize) const;

	 /** sets the color of the indicated pixel to the given color.*/
	 void setPixel (int layer = 0, int row = 0, int col = 0, color c = white) {this->image[layer].setData_noClusterUpdate(row, col, c);}
	 
	 /** Returns the color of the given pixel in the given layer. */
	 color getPixel (int layer, int row, int col) const {return (color)this->image[layer].getValue(row, col);}

	 color getPixelValueWithRotationalIndex (int layer, int row, int col, int nbIndex) const {return (color)this->image[layer].getValueWithRotationalIndex(row,col, nbIndex);}

	 /** Copies the images to the array of imagematrices whose pointer is given.*/
	 void copyImagesTo(ImageMatrix images[], int size) const;

	 int getRowNum () const {return this->image[0].getRowNum();}
	 int getColNum () const {return this->image[0].getColNum();}
	 EightLayerIM () : validImages(0) {};				//!<Calls the default constructor on each image
	 EightLayerIM (ImageMatrix imageArray[], int validImages);	//!<User should explicitly define an array of imagmatrix and use it as a parameter here.
	 //EightLayerIM (int validImages, string fileName);	//!<THIS DOES NOT WORK YET! Will read the bits from a grayscale image.
	 EightLayerIM (const EightLayerIM& other);
	 /** 
	  * if type = "txts": Creates an eightlayerImage by reading from 'layers' number of files whose basename is given:
	  * file1: baseName_start.bmp
	  * file2: baseName_start+1.bmp
	  * and so on.
	  *
	  * if type = "bmp": Creates an eightlayerImage by reading from 'layers' number of bits per pixel in the input bitmap file.
	  *
	  * if type = "txt": Creates an eightlayerImage by reading from 'layers' number of bits per pixel in the input text file (values are between 0 to 255).
	  */
	 EightLayerIM (string baseName, int layers, string type = "bmp"); 

	 /**
	  * This function creates a matrix in a text file, where each element is a number between 0 to 255.
	  * Each element in the text file has the combined info of all the imagematrices in the object. 
	  * The resulted file can then be used to create a .bmp file.
	  * \param targetFileName the name of the output file. The function does not add the extension name, it's up to caller to give the name and extention.
	  * \param layers the number of layers to be put together to create the outputvalues. if -1, the
	  * function consider all the valid images it has.
	  */
	 bool flattenLayersToTextFile(string targetFileName, int layers = -1) const;

	 /**
	  * Similar to flattenLayersToTextFile(), but writes the contents to an "EXISTING" bmp file of the same size.
	  */
	 bool saveToBlankBMP(string fileName, int layers = -1) const;

	 void writeToBinaryTextFiles (const string baseName, const int layers = BITS_PER_PIXEL) const;

	 EightLayerIM& operator= (const EightLayerIM& other);
 };
